package com.ruoyi.yyq.controller;

import java.math.BigDecimal;
import java.util.*;
import java.io.IOException;
import java.util.stream.Collectors;
import javax.annotation.PostConstruct;
import javax.servlet.http.HttpServletResponse;

import com.ruoyi.common.core.constant.SecurityConstants;
import com.ruoyi.common.security.annotation.InnerAuth;
import com.ruoyi.user.api.domain.CarUser;
import com.ruoyi.yyq.domain.CarCoupon;
import com.ruoyi.yyq.domain.CarMerchant;
import com.ruoyi.yyq.domain.CarServiceDetails;
import com.ruoyi.yyq.domain.vo.CarOrderES;
import com.ruoyi.yyq.domain.vo.CarOrderVo;
import com.ruoyi.yyq.domain.vo.EvaluationCar;
import com.ruoyi.yyq.service.ICarCouponService;
import com.ruoyi.yyq.service.ICarMerchantService;
import com.ruoyi.yyq.service.ICarServiceDetailsService;
import com.ruoyi.yyq.service.impl.CarServiceDetailsServiceImpl;
import org.elasticsearch.client.ml.job.results.Bucket;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.Aggregations;
import org.elasticsearch.search.aggregations.bucket.terms.ParsedStringTerms;
import org.elasticsearch.search.aggregations.bucket.terms.Terms;
import org.elasticsearch.search.aggregations.metrics.*;
import org.springframework.amqp.rabbit.core.RabbitTemplate;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.elasticsearch.core.*;
import org.springframework.data.elasticsearch.core.document.Document;
import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.web.bind.annotation.*;
import com.ruoyi.common.log.annotation.Log;
import com.ruoyi.common.log.enums.BusinessType;
import com.ruoyi.common.security.annotation.RequiresPermissions;
import com.ruoyi.yyq.domain.CarOrder;
import com.ruoyi.yyq.service.ICarOrderService;
import com.ruoyi.common.core.web.controller.BaseController;
import com.ruoyi.common.core.web.domain.AjaxResult;
import com.ruoyi.common.core.utils.poi.ExcelUtil;
import com.ruoyi.common.core.web.page.TableDataInfo;

/**
 * 订单信息Controller
 *
 * @author ruoyi
 * @date 2025-05-12
 */
@RestController
@RequestMapping("/orders")
@CrossOrigin
public class CarOrderController extends BaseController {
    @Autowired
    private ICarOrderService carOrderService;
    @Autowired
    private RabbitTemplate rabbitTemplate;
    @Autowired
    private ICarServiceDetailsService detailsService;
    @Autowired
    private ICarMerchantService merchantService;
    @Autowired
    private ICarCouponService couponService;
    @Autowired
    private ElasticsearchRestTemplate elasticsearchRestTemplate;

    /**
     * 对外暴露查询订单信息列表
     */
    @InnerAuth
    @GetMapping("/getlist")
    public TableDataInfo getlist(CarOrder carOrder) {

        List<CarOrder> list = carOrderService.selectCarOrderList(carOrder);
        return getDataTable(list);
    }

    /**
     * 对外暴露新增订单信息
     */
    @InnerAuth
    @PostMapping("/getadd")
    public AjaxResult getadd(@RequestBody CarOrder carOrder) {

        AjaxResult result = toAjax(carOrderService.insertCarOrder(carOrder));
        if (result.isSuccess()) {
            // 发送订单信息到队列
            rabbitTemplate.convertAndSend("order_queue", carOrder);
            // 在控制台打印订单信息
            System.out.println("已发送订单信息到队列: " + carOrder);
        }
        return result;
        //return toAjax(carOrderService.insertCarOrder(carOrder));

    }

    /**
     * 对外暴露修改订单信息
     */
    @InnerAuth
    @PutMapping("/getedit")
    public AjaxResult getedit(@RequestBody CarOrder carOrder) {
        return toAjax(carOrderService.updateCarOrder(carOrder));
    }

    /**
     * 对外暴露删除订单信息
     */
    @InnerAuth
    @DeleteMapping("/getremove/{ids}")
    public AjaxResult getremove(@PathVariable Long[] ids) {

        return toAjax(carOrderService.deleteCarOrderByIds(ids));
    }
    /**
     * 对外暴露根据核销码查询订单信息
     */
//    @InnerAuth
//    @GetMapping(value = "/getcode")
//    public AjaxResult getcode(String verificationCode)
//    {
//        return success(carOrderService.selectCarOrderByCode(verificationCode));
//    }
    @RequiresPermissions("ordersinfo:orders:query")
    @GetMapping(value = "/getcode")
    public AjaxResult getcode(String verificationCode)
    {
        CarOrder carOrder = carOrderService.selectCarOrderByCode(verificationCode);

        return success(carOrder);
    }




    /**
     * 在 Bean 初始化完成后执行，检查并创建 Elasticsearch 索引
     */
//    @PostConstruct
    private void initElasticsearchIndex() {
        //基于CarOrderES类创建操作es数据对象
        IndexOperations indexOps = elasticsearchRestTemplate.indexOps(CarOrderES.class);
        //判断索引是否存在
        if (!indexOps.exists()) {
            //不存在，创建索引
            indexOps.create();
//            // 创建映射，将映射信息保存到es中
//            indexOps.putMapping(indexOps.createMapping());
            //在内存中创建映射
            Document document = indexOps.createMapping();
            //同步映射更新到es中
            indexOps.putMapping(document);
        }
    }

    /**
     * 收入，订单量统计
     * @return
     */
    @RequiresPermissions("ordersinfo:orders:list")
    @GetMapping("/getlistes")
    public AjaxResult getlistes() {
        initElasticsearchIndex();
        // 构建查询条件
        NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();
        // 设置查询类型：match、term、fuzzy、range...
        // 查询所有订单
        queryBuilder.withQuery(QueryBuilders.matchAllQuery());

        // 假设要过滤的订单状态为 5（已完成），可根据实际需求修改
        long targetStatus = 5L;
        // 添加状态过滤条件
        queryBuilder.withFilter(QueryBuilders.termQuery("status", targetStatus));

        queryBuilder.addAggregation(AggregationBuilders.terms("mid").field("mid")
              .subAggregation(AggregationBuilders.terms("orderTime").field("orderTime")
                  .subAggregation(AggregationBuilders.sum("sumprice").field("price"))// 收入求和
                      .subAggregation(AggregationBuilders.sum("orderCount").field("id"))));// 订单量统计
        /*
         * searchHits:代表查询到的整个结果集
         * searchHits.getSearchHits():代表获取结果集中hits中的文档结果集
         * searchHits.getAggregations(): 代表获取聚合度量结果
         * */
        SearchHits<CarOrderES> searchHits = elasticsearchRestTemplate.search(queryBuilder.build(),
                CarOrderES.class, IndexCoordinates.of("carorderes"));

        // 解析聚合结果
        List<Map<String, Object>> resultList = new ArrayList<>();
        Aggregations aggregations = (Aggregations) searchHits.getAggregations().aggregations();
        if (aggregations != null) {
            ParsedStringTerms orderDateBuckets = aggregations.get("mid");
            for (Terms.Bucket bucket : orderDateBuckets.getBuckets()) {
                Map<String, Object> resultMap = new HashMap<>();
                // 获取订单日期
                resultMap.put("orderDate", bucket.getKeyAsString());
                // 获取收入
                ParsedSum revenue = bucket.getAggregations().get("sumprice");
                resultMap.put("sumprice", revenue.getValue());
                // 获取订单量
                ParsedValueCount orderCount = bucket.getAggregations().get("orderCount");
                resultMap.put("orderCount", orderCount.getValue());
                resultList.add(resultMap);
            }
        }
        return AjaxResult.success(resultList);
    }
    /**
     * 收入分布，订单分布统计
     * @return
     */
    @RequiresPermissions("ordersinfo:orders:list")
    @GetMapping("/getlistes1")
    public AjaxResult getlistes1() {
        initElasticsearchIndex();
        // 构建查询条件
        NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();
        // 设置查询类型：match、term、fuzzy、range...
        // 查询所有订单
        queryBuilder.withQuery(QueryBuilders.matchAllQuery());

        // 假设要过滤的订单状态为 5（已完成），可根据实际需求修改
        long targetStatus = 5L;
        // 添加状态过滤条件
        queryBuilder.withFilter(QueryBuilders.termQuery("status", targetStatus));

        queryBuilder.addAggregation(AggregationBuilders.terms("mid").field("mid")
                .subAggregation(AggregationBuilders.terms("orderTime").field("orderTime")
                        .subAggregation(AggregationBuilders.terms("serviceId").field("serviceId")
                                .subAggregation(AggregationBuilders.sum("sumprice").field("price"))// 收入求和
                                .subAggregation(AggregationBuilders.sum("orderCount").field("id")))));// 订单量统计
        /*
         * searchHits:代表查询到的整个结果集
         * searchHits.getSearchHits():代表获取结果集中hits中的文档结果集
         * searchHits.getAggregations(): 代表获取聚合度量结果
         * */
        SearchHits<CarOrderES> searchHits1 = elasticsearchRestTemplate.search(queryBuilder.build(),
                CarOrderES.class, IndexCoordinates.of("carorderes"));

        // 解析聚合结果
        List<Map<String, Object>> resultList = new ArrayList<>();
        Aggregations aggregations = (Aggregations) searchHits1.getAggregations().aggregations();
        if (aggregations != null) {
            // 获取 mid 聚合结果
            Terms midTerms = aggregations.get("mid");
            if (midTerms != null) {
                for (Terms.Bucket midBucket : midTerms.getBuckets()) {
                    // 获取 mid 值
                    Long mid = midBucket.getKeyAsNumber().longValue();
                    // 获取 orderTime 子聚合结果
                    Terms orderTimeTerms = midBucket.getAggregations().get("orderTime");
                    if (orderTimeTerms != null) {
                        for (Terms.Bucket orderTimeBucket : orderTimeTerms.getBuckets()) {
                            // 获取 orderTime 值
                            String orderTime = orderTimeBucket.getKeyAsString();
                            // 获取 serviceId 子聚合结果
                            Terms serviceIdTerms = orderTimeBucket.getAggregations().get("serviceId");
                            if (serviceIdTerms != null) {
                                for (Terms.Bucket serviceIdBucket : serviceIdTerms.getBuckets()) {
                                    // 获取 serviceId 值
                                    Long serviceId = serviceIdBucket.getKeyAsNumber().longValue();
                                    // 获取收入
                                    Sum sumPrice = serviceIdBucket.getAggregations().get("sumprice");
                                    double revenue = sumPrice.getValue();
                                    // 获取订单量
                                    ValueCount orderCount = serviceIdBucket.getAggregations().get("orderCount");
//                                    long count = orderCount.getValueAsLong();
                                    // 修改为调用 getValue 方法并转换为 long 类型
                                    long count = orderCount.getValue();

                                    // 封装结果
                                    Map<String, Object> resultMap = new HashMap<>();
                                    resultMap.put("mid", mid);
                                    resultMap.put("orderTime", orderTime);
                                    resultMap.put("serviceId", serviceId);
                                    resultMap.put("sumprice", revenue);
                                    resultMap.put("orderCount", count);
                                    resultList.add(resultMap);
                                }
                            }
                        }
                    }
                }
            }
        }
        return AjaxResult.success(resultList);
    }

    /**
     * 查询订单信息列表
     */
    @RequiresPermissions("ordersinfo:orders:list")
    @GetMapping("/list")
    public TableDataInfo list(CarOrder carOrder) {
        startPage();
        List<CarOrder> list = carOrderService.selectCarOrderList(carOrder);
        return getDataTable(list);
    }

    /**
     * 导出订单信息列表
     */
    @RequiresPermissions("ordersinfo:orders:export")
    @Log(title = "订单信息", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, CarOrder carOrder) {
        List<CarOrder> list = carOrderService.selectCarOrderList(carOrder);
        ExcelUtil<CarOrder> util = new ExcelUtil<CarOrder>(CarOrder.class);
        util.exportExcel(response, list, "订单信息数据");
    }

    /**
     * 获取订单信息详细信息
     */
    @RequiresPermissions("ordersinfo:orders:query")
    @GetMapping(value = "/{id}")
    public AjaxResult getInfo(@PathVariable("id") Long id) {
//        return success(carOrderService.selectCarOrderById(id));
        CarOrderVo carOrderVo = new CarOrderVo(carOrderService.selectCarOrderById(id));
        CarServiceDetails details = detailsService.selectCarServiceDetailsById(carOrderVo.getServiceId());
        carOrderVo.setCarServiceDetails(details);
        CarMerchant carMerchant = merchantService.selectCarMerchantById(carOrderVo.getMid());
        carOrderVo.setShopName(carMerchant.getName());
        CarCoupon carCoupon = couponService.selectCarCouponById(carOrderVo.getShopCouponId());
        if (carCoupon.getType().equals("满减券")) {
            carOrderVo.setZTPrice(carCoupon.getPreferentialMoney());
        } else {
            BigDecimal discount = BigDecimal.valueOf(carCoupon.getDiscount());
            carOrderVo.setZTPrice(carOrderVo.getCarServiceDetails().getPresentPrice().multiply(discount).doubleValue());
        }
        // 处理订单状态
        int status = Math.toIntExact(carOrderVo.getStatus());
        switch (status) {
            case 0:
                carOrderVo.setStatusName("待支付");
                break;
            case 1:
                carOrderVo.setStatusName("待使用");
                break;
            case 2:
                carOrderVo.setStatusName("待评价");
                break;
            case 3:
                carOrderVo.setStatusName("已取消");
                break;
            case 4:
                carOrderVo.setStatusName("已退款");
                break;
            case 5:
                carOrderVo.setStatusName("已完成");
                break;
        }
        return success(carOrderVo);
    }


    /**
     * 新增订单信息
     */
    @RequiresPermissions("ordersinfo:orders:add")
    @Log(title = "订单信息", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody CarOrder carOrder) {
        AjaxResult result = toAjax(carOrderService.insertCarOrder(carOrder));
        if (result.isSuccess()) {
            // 发送订单信息到队列
            rabbitTemplate.convertAndSend("order_queue", carOrder);
            // 在控制台打印订单信息
            System.out.println("已发送订单信息到队列: " + carOrder);
        }
        return result;
        //return toAjax(carOrderService.insertCarOrder(carOrder));

    }

    /**
     * 修改订单信息
     */
    @RequiresPermissions("ordersinfo:orders:edit")
    @Log(title = "订单信息", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody CarOrder carOrder) {
        return toAjax(carOrderService.updateCarOrder(carOrder));
    }

    /**
     * 删除订单信息
     */
    @RequiresPermissions("ordersinfo:orders:remove")
    @Log(title = "订单信息", businessType = BusinessType.DELETE)
    @DeleteMapping("/{ids}")
    public AjaxResult remove(@PathVariable Long[] ids) {

        return toAjax(carOrderService.deleteCarOrderByIds(ids));
    }
    /**
     * 根据服务详情id查询服务项目名
     */
    @RequiresPermissions("ordersinfo:orders:query")
    @GetMapping(value = "/selectServiceName/{id}")
    public String selectCarOrderWithServiceName(@PathVariable Long id){
        return carOrderService.selectCarOrderWithServiceName(id);
    }
    /**
     * 修改订单使用时间为当前时间，并将状态改为5（已完成）
     */
    @RequiresPermissions("ordersinfo:orders:edit")
    @Log(title = "订单信息", businessType = BusinessType.UPDATE)
    @PutMapping("/complete")
    public AjaxResult completeOrder(@RequestBody CarOrder carOrder) {
        carOrder.setUseTime(new Date()); // 设置使用时间为当前时间
        carOrder.setStatus(5L); // 设置状态为5（已完成）
        return toAjax(carOrderService.updateCarOrder(carOrder));
    }

    /**
     * 获取店铺下所有订单的评价信息
     */
    @GetMapping("/evaluations/{mid}")
    public AjaxResult getEvaluationsByMid(@PathVariable("mid") Long mid)
    {
        return success(carOrderService.selectEvaluationsByMid(mid));
    }

    /**
     * 根据用户ID查询订单信息（包含店铺名和服务项目名称）
     */
    @RequiresPermissions("ordersinfo:orders:query")
    @GetMapping("/byUserId/{uid}")
    public TableDataInfo getOrdersByUserId(@PathVariable Long uid) {
        startPage();
        // 1. 查询用户的所有订单
        List<CarOrder> orders = carOrderService.selectCarOrderByUserId(uid);

        // 2. 转换为Map并添加关联数据
        List<Map<String, Object>> result = orders.stream().map(order -> {
            Map<String, Object> map = new HashMap<>();

            // 明确添加订单数据
            map.put("order", order);  // 将整个订单对象放入map中

            // 复制CarOrder的所有属性到Map
            BeanUtils.copyProperties(order, map);

            // 查询店铺名
            CarMerchant merchant = merchantService.selectCarMerchantById(order.getMid());
            map.put("shopName", merchant != null ? merchant.getName() : null);

            // 查询服务项目名称
            CarServiceDetails details = detailsService.selectCarServiceDetailsById(order.getServiceId());
            map.put("serviceName", details != null ? details.getName() : null);

            return map;
        }).collect(Collectors.toList());

        return getDataTable(result);
    }
}
